package com.jee.ssm.modules.ssm.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import javax.servlet.http.HttpServletRequest;

import com.jee.ssm.common.config.ShopInfo;
import com.jee.ssm.common.utils.wechat.*;
import com.jee.ssm.model.*;
import com.jee.ssm.modules.billRecord.services.BillRecordService;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.jee.ssm.common.utils.CalculateUtils;
import com.jee.ssm.common.utils.HttpUtils;
import com.jee.ssm.common.utils.PushUtils;
import com.jee.ssm.common.utils.TimeUtils;
import com.jee.ssm.common.utils.UUIDFactory;
import com.jee.ssm.common.utils.hik.HikUtils;
import com.jee.ssm.model.ccb.PayReceive;
import com.jee.ssm.model.ccb.QueryReceive;
import com.jee.ssm.model.hik.ChargeRecord;
import com.jee.ssm.model.hik.HikReturn;
import com.jee.ssm.model.hik.receive.HikBill;
import com.jee.ssm.model.hik.receive.ParkDepotInfo;
import com.jee.ssm.model.json.Tip;
import com.jee.ssm.modules.hikBill.services.HikBillService;
import com.jee.ssm.modules.parkDepot.services.ParkDepotService;
import com.jee.ssm.modules.personalMessage.services.PersonalMessageService;
import com.jee.ssm.modules.user.services.UserService;
import com.jee.ssm.modules.userPlate.services.UserPlateService;

import COM.CCB.EnDecryptAlgorithm.MCipherEncryptor;

/**
 * 首页访问控制 Controller
 * @author GaoXiang
 * @version 1.0
 */
@Controller
public class IndexController{
	@Autowired
	BillRecordService billRecordService;
	private Logger logger = Logger.getLogger(IndexController.class);

    /**
     * 前台首页
     * @return 前台首页页面
     */
    @RequestMapping(value = "/")
    public String present(Model model) {
    	//停车场数量
    	int parkDepotNumbers = 0;
    	//停车位总数
    	Integer totalParklot = 0;
    	//剩余停车位数量
    	Integer parklotLeft = 0;
    	//已使用停车位总数
    	int parklotUsing = 0;
    	//当日停车费总金额
    	BigDecimal totalFee = new BigDecimal("0");
    	List<ParkDepotInfo> list = HikUtils.getParkingList();
    	if(list.size() > 0) {
    		for(ParkDepotInfo p : list) {
                ParkDepot parkDepot = parkDepotService.findByHikId(p.getParkCode());
                if(parkDepot != null) {
                	parkDepotNumbers += 1;
                	totalParklot += p.getTotalPlot();
                	parklotLeft += p.getLeftPlot();
                	List<ChargeRecord> chargeRecords = HikUtils.getChargeRecords(p.getParkCode());
                	for(ChargeRecord c : chargeRecords) {
                		totalFee = totalFee.add(new BigDecimal(c.getPayMoney()));
                	}
                }
            }
    	}
    	parklotUsing = totalParklot - parklotLeft;
    	model.addAttribute("parkDepotNumbers", parkDepotNumbers);
    	model.addAttribute("totalParklot", totalParklot);
    	model.addAttribute("parklotLeft", parklotLeft);
    	model.addAttribute("parklotUsing", parklotUsing);
    	//注册用户数量
    	model.addAttribute("userNumbers", userService.listUserToCount(null).size());
    	
    	model.addAttribute("totalFee", totalFee);
//        return "manager/present/index";
//        return "manager/present/oracle";
        return "manager/present/block";
    }
	/**
	 * 用户扫码推送
	 *
	 * @param
	 * @return 返回展示页面
	 */
	@RequestMapping(value = "/scanToPay")
	public String scanToPay(Model model,HttpServletRequest request) throws  Exception {
		logger.info("----------------------用户扫码推送----------------------");
		Tip tip = new Tip();
		String state= request.getParameter("state");
		System.out.println(state);
		String codeAndNo[] = new String[2];
		codeAndNo = state.split(",");
		HikBill hikBill = new HikBill();
		hikBill.setLaneNo(codeAndNo[1]);
		hikBill.setParkCode(codeAndNo[0]);
		hikBill = hikBillService.findByLane(hikBill);
		if(hikBill.getId().equals(null)){
			return "null";
		}
		Tip hkTip =new Tip();
		hkTip = HikUtils.getParkingPaymentInfoRequestBO(hikBill.getPlateColor(),hikBill.getPlateNo());
		HikBill hikbill1 = (HikBill) hkTip.getData();
		hikBill.setNeedPay(hikbill1.getTotalCost());
		hikBill.setBillNo(hikbill1.getBillCode());
		hikBillService.updateById(hikBill);
		String openId = WxUtils.getOpenId(request.getParameter("code"));
		String number = UUIDFactory.get12Id();
		BigDecimal money = CalculateUtils.divide(hikBill.getNeedPay(), 100);



//		BigDecimal money = CalculateUtils.null2Decimal(hikBill.getNeedPay());
		BillRecord billRecord = new BillRecord(UUIDFactory.getStringId(),
				number,
				money,
				new Date(),
				"无用户车道扫码支付",
				"+",
				0,
				1,
				3,
				hikBill.getId(),
				"无用户车道扫码支付",
				openId,
				openId,
				"0",
				openId,
				"",
				"8",
				hikBill.getInDateTime(),
				hikBill.getOutDateTime(),
				hikBill.getParkTime(),
				hikBill.getPlateNo()
		);
		PaymaxConfig config = new PaymaxConfig(ShopInfo.WX_GZ_APPID, ShopInfo.WX_PROGRAM_MECHID, ShopInfo.WX_PROGRAM_KEY, ShopInfo.WX_RECHARGE_NOTIFYURL, ShopInfo.WX_TRADETYPE_PROGRAM, ShopInfo.WX_URL, ShopInfo.POST);
		Unifiedorder unifiedorder = new Unifiedorder();
		unifiedorder.setAppid(config.getAppId());
		unifiedorder.setMch_id(config.getMchId());
		unifiedorder.setNonce_str(RandCharsUtils.getRandomString(16));
		unifiedorder.setBody(billRecord.getContent());
		unifiedorder.setDetail(billRecord.getIntro());
		unifiedorder.setAttach("");
		unifiedorder.setOut_trade_no(number);
		unifiedorder.setTotal_fee(hikBill.getNeedPay());
		unifiedorder.setSpbill_create_ip(request.getRemoteAddr());
		unifiedorder.setTime_start(RandCharsUtils.timeStart());
		unifiedorder.setTime_expire(RandCharsUtils.timeExpire());
		unifiedorder.setNotify_url(config.getNotifyUrl());
		unifiedorder.setTrade_type(config.getTradeType());
		unifiedorder.setOpenid(openId);
		tip = new WXPay().payByProgramApp(unifiedorder, config);
		if (tip.getSuccess()) {
			try {
				logger.info("-----------------用户扫码支付信息保存中-----------------------------");
				logger.info(billRecord.toString());
				billRecordService.insert(billRecord);
			} catch (Exception e) {
				e.printStackTrace();
				com.jee.ssm.common.config.Logger.info("编号为：" + number + "的订单保存失败");
			}
		}
		model.addAttribute("data", tip.getData());
		model.addAttribute("money",money);
		model.addAttribute("hikBill", hikBill);
		return "manager/qcode/index";
	}




    /**
     * 海康账单推送
     * @param sign 加密标识
     * @param request 推送数据
     * @return 是否抬杆
     */
	@RequestMapping(value = "/hikBillpay")
	@ResponseBody
	public HikReturn hikBillpay(String sign, HttpServletRequest request) {
		logger.info("----------------------海康账单推送----------------------");
		HikReturn hikReturn = new HikReturn();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
			String line;
			StringBuilder sb = new StringBuilder();
			while((line = br.readLine()) != null){
				sb.append(line);
			}
			HikBill hb = new HikBill();
			hb = JSONObject.parseObject(sb.toString(), HikBill.class);
			String hikId = UUIDFactory.getStringId();
			hb.setId(hikId);
			hb.setPlateNo((hb.getBillNo() != null && !"".equals(hb.getPlateNo())) ? hb.getPlateNo().toUpperCase() : "");
			hb.setInDateTime(TimeUtils.getDateByMillionSeconds(hb.getInTime()));
			hb.setOutDateTime(TimeUtils.getDateByMillionSeconds(hb.getOutTime()));
			hb.setPayStatus(0);
			hb.setStatus(1);
			hb.setType(1);
			hb.setCreateTime(new Date());
			hb.setUpdateTime(new Date());
			logger.info("当前用户的车牌号："+hb.getPlateNo());
			logger.info("当前用户的车牌颜色："+String.valueOf(hb.getPlateColor()));
			UserPlate up = new UserPlate(hb.getPlateNo(), String.valueOf(hb.getPlateColor()));
			up = userPlateService.findByNumberAndColour(up);
//			logger.info(up.toString());
			//初始状态0代表线上无法做任何处理，1：余额支付成功，2：需要建行支付，3：给用户返回账单
			int status = 0;
			BigDecimal money = CalculateUtils.divide(hb.getNeedPay(), 100);
			if("冀C2W135".equals(hb.getPlateNo()) || "冀B43V25".equals(hb.getPlateNo()) || "鲁A00922".equals(hb.getPlateNo()) || "冀C95N28".equals(hb.getPlateNo()) || "鲁AH2N35".equals(hb.getPlateNo())) {
				System.out.println("车牌号码为：" + hb.getPlateNo());
				System.out.println("是否查询到车牌：" + (up != null));

			}
			if(up != null) {
				logger.info("用户和车牌中有数据来");
				User user = userService.selectById(up.getUserId());
				System.out.println("是否查询到用户：" + (user != null));
				if(user != null) {
					hb.setUserId(user.getId());
					hb.setUserName(user.getUserName());
					hb.setUserPhone(user.getPhone());
					hb.setRealName(user.getName());
					hb.setIdNumber(user.getIdNumber());

//					if("冀C2W135".equals(hb.getPlateNo()) || "冀B43V25".equals(hb.getPlateNo()) || "鲁A00922".equals(hb.getPlateNo()) || "冀C95N28".equals(hb.getPlateNo()) || "鲁AH2N35".equals(hb.getPlateNo())) {
						System.out.println("是否开通自动扣款：" + (up.getAutoPay() == 1));
						if(up.getAutoPay() == 1) {
							System.out.println("余额是否充足：" + (user.getWalletBalance().compareTo(money) != -1));
							if(user.getWalletBalance().compareTo(money) != -1) {
								user.setWalletBalance(CalculateUtils.subtract(user.getWalletBalance(), money));
								try {
									logger.info("-------------------海康账单余额支付--------------");
									logger.info("-------------------保存到自己平台的账单信息--------------");
									userService.updateWalletBalanceById(user, "-", money, "支付车牌号码为" + hb.getPlateNo() + "的车辆于在" + hb.getParkName() + "的停车费" + money + "元", 1, 3, hikId, "余额支付停车费", "0",hb.getInDateTime(),hb.getOutDateTime(),hb.getParkTime(),hb.getPlateNo());
									hb.setPayStatus(1);
									hb.setPayMethod(1);
									status = 1;
                                    PersonalMessage pm = new PersonalMessage(UUIDFactory.getStringId(), "自动扣费成功", user.getId(), user.getPhone(), user.getUserName(), user.getName(), user.getIdNumber(), 0, 0, new Date(), new Date(), "车牌号码为" + hb.getPlateNo() + "的车辆在" + hb.getParkName() + "自动扣费" + money + "元");
                                    personalMesssageService.insert(pm);
									try {
										PushUtils.pushPersonalMessageToOne(pm);
										PushUtils.pushPersonalMessageToOneIos(pm);
									}catch (Exception e8){
										PushUtils.pushPersonalMessageToOneIos(pm);
									}
								} catch (Exception e) {
									e.printStackTrace();
									//自动扣款失败 发消息提醒推送账单
									PersonalMessage pm = new PersonalMessage(UUIDFactory.getStringId(), "您有一条未支付订单", user.getId(), user.getPhone(), user.getUserName(), user.getName(), user.getIdNumber(), 0, 0, new Date(), new Date(), "车牌号码为" + hb.getPlateNo() + "的车辆在" + hb.getParkName() + "的账单未支付，账单金额为" + money + "元");
									try {
										personalMesssageService.insert(pm);
									} catch (Exception e1) {
										System.out.println("消息保存失败 ");
									}
									try {
										PushUtils.pushPersonalMessageToOne(pm);
										PushUtils.pushPersonalMessageToOneIos(pm);
									}catch (Exception e9){
										try {
											PushUtils.pushPersonalMessageToOneIos(pm);
										} catch (Exception e1) {
											e1.printStackTrace();

										}
									}
									status = 3;
								}
							} else {
								//余额不足 建行无感支付
								//status = 2;
								status = 3;
								//未开通自动扣款 发消息提醒推送账单
								PersonalMessage pm = new PersonalMessage(UUIDFactory.getStringId(), "您有一条未支付订单", user.getId(), user.getPhone(), user.getUserName(), user.getName(), user.getIdNumber(), 0, 0, new Date(), new Date(), "车牌号码为" + hb.getPlateNo() + "的车辆在" + hb.getParkName() + "的账单未支付，账单金额为" + money + "元");
								try {
									personalMesssageService.insert(pm);
								} catch (Exception e) {
									System.out.println("消息保存失败 ");
								}
								try {
									PushUtils.pushPersonalMessageToOne(pm);
									PushUtils.pushPersonalMessageToOneIos(pm);
								}catch (Exception e){
									try {
										PushUtils.pushPersonalMessageToOneIos(pm);
									} catch (Exception e1) {
										e1.printStackTrace();
									}
								}
							}
						} else {
							//未开通自动扣款 发消息提醒推送账单
							PersonalMessage pm = new PersonalMessage(UUIDFactory.getStringId(), "您有一条未支付订单", user.getId(), user.getPhone(), user.getUserName(), user.getName(), user.getIdNumber(), 0, 0, new Date(), new Date(), "车牌号码为" + hb.getPlateNo() + "的车辆在" + hb.getParkName() + "的账单未支付，账单金额为" + money + "元");
							try {
								personalMesssageService.insert(pm);
							} catch (Exception e) {
								System.out.println("消息保存失败 ");
							}
							try {
								PushUtils.pushPersonalMessageToOne(pm);
								PushUtils.pushPersonalMessageToOneIos(pm);
							}catch (Exception e){
								try {
									PushUtils.pushPersonalMessageToOneIos(pm);
								} catch (Exception e1) {
									e1.printStackTrace();
								}
							}
							status = 3;
						}
//					}
				} else {
					//查询到车牌但是没有查到用户，属于系统数据异常
					//status = 2;
					status = 5;

				}
			} else {
				//status = 2;
				status = 3;

			}
//			if(status == 2) {
//				System.out.println("执行了建行的无感支付");
//				//调用建行无感支付
//				Tip tip = checkStatus(hb.getPlateNo());
//				if(tip.getSuccess()) {
//					tip = payByCCB(String.valueOf(money), hb.getPlateNo());
//					if(tip.getSuccess()) {
//						System.out.println("无感支付成功");
//						hb.setPayStatus(1);
//						hb.setPayMethod(4);
//						status = 1;
//					} else {
//						System.out.println("无感支付失败");
//						status = 5;
//					}
//				} else {
//					System.out.println("未开通无感支付");
//					status = 5;
//				}
//
//			}

			logger.info("入场时间：" + TimeUtils.getStringDateByMillionSeconds(hb.getInTime()));
			logger.info("离场时间：" + TimeUtils.getStringDateByMillionSeconds(hb.getOutTime()));

			try {
				logger.info("-------------------保存海康账单中--------------");
				logger.info(hb.toString());
				hikBillService.insert(hb);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("海康账单保存异常");
			}

			hikReturn = new HikReturn("200", "请求成功", hikId);
			if(status == 1) {//1 抬杆 // 0不抬杆
				hikReturn.setStatus(1);
			} else {
				hikReturn.setStatus(0);
			}
			
		} catch(IOException e) {
//			e.printStackTrace();
			hikReturn = new HikReturn("500", "上报数据异常", 0, "000000000000000");
		}

		logger.info("---------------返回处理信息:"+hikReturn+"---------------------");
		return hikReturn;
	}







	public Tip checkStatus(String AUTHNO) {
		Tip tip = new Tip();
		String url = "https://ibsbjstar.ccb.com.cn/CCBIS/B2CMainPlat_00_ENPAY";

		String MERCHANTID = "105910200793152";

		String POSID = "021875917";

		String BRANCHID = "130000000";

		String strSrcParas = "MERFLAG=1&MERCHANTID=" + MERCHANTID + "&POSID=" + POSID + "&BRANCHID=" + BRANCHID + "&AUTHNO=" + AUTHNO + "&TXCODE=WGZF01";

		logger.info(strSrcParas);

		String strKey = "d5475cd40d0e98cddaa3dcf9020111";

		MCipherEncryptor ccbEncryptor = new MCipherEncryptor(strKey);

		try {
			String ccbParam = ccbEncryptor.doEncrypt(strSrcParas);

			NameValuePair[] data = {
					new NameValuePair("MERFLAG", "1"),
					new NameValuePair("MERCHANTID", MERCHANTID),
					new NameValuePair("POSID", POSID),
					new NameValuePair("BRANCHID", BRANCHID),
					new NameValuePair("AUTHNO", AUTHNO),
					new NameValuePair("TXCODE", "WGZF01"),
					new NameValuePair("ccbParam", ccbParam)
			};

			String result = HttpUtils.doPost(url, data);
			QueryReceive qr = JSONObject.parseObject(result, QueryReceive.class);
			if("1".equals(qr.getAUTHSTATUS())) {
				//查询结果1为已绑定建行卡，这里处理结果
				tip = new Tip("");
			} else {
				tip = new Tip(3, "未开通无感支付");
			}
		} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | ShortBufferException
				| IllegalBlockSizeException | BadPaddingException | NoSuchProviderException
				| InvalidAlgorithmParameterException | UnsupportedEncodingException e) {
			e.printStackTrace();
			tip = new Tip(2, "加密失败");
		} catch (IOException e) {
			e.printStackTrace();
			tip = new Tip(1, "请求异常");
		}

		return tip;
	}

	public Tip payByCCB(String AMOUNT, String AUTHNO) {

		Tip tip = new Tip();
		
		String url = "https://ibsbjstar.ccb.com.cn/CCBIS/B2CMainPlat_00_ENPAY";

		String MERCHANTID = "105910200793152";

		String POSID = "021875917";

		String BRANCHID = "130000000";

		String ORDERID = UUIDFactory.get32Id().substring(0, 30);

		String strSrcParas = "MERFLAG=1&MERCHANTID=" + MERCHANTID + "&POSID=" + POSID + "&BRANCHID=" + BRANCHID + "&ORDERID=" + ORDERID +"&AUTHNO=" + AUTHNO + "&AMOUNT=" + AMOUNT + "&TXCODE=WGZF00";

		String strKey = "d5475cd40d0e98cddaa3dcf9020111";

		MCipherEncryptor ccbEncryptor = new MCipherEncryptor(strKey);

		try {
			String ccbParam = ccbEncryptor.doEncrypt(strSrcParas);

			NameValuePair[] data = {
					new NameValuePair("MERFLAG", "1"),
					new NameValuePair("MERCHANTID", MERCHANTID),
					new NameValuePair("POSID", POSID),
					new NameValuePair("BRANCHID", BRANCHID),
					new NameValuePair("ORDERID", ORDERID),
					new NameValuePair("AUTHNO", AUTHNO),
					new NameValuePair("AMOUNT", AMOUNT),
					new NameValuePair("TXCODE", "WGZF00"),
					new NameValuePair("ccbParam", ccbParam)
			};
			String result = HttpUtils.doPost(url, data);
			PayReceive pr = JSONObject.parseObject(result, PayReceive.class);
			if("Y".equals(pr.getRESULT())) {
				//返回扣费成功，这里处理结果
				tip = new Tip("扣费成功");
			} else {
				tip = new Tip(1, "未开通无感支付");
			}
		} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | ShortBufferException
				| IllegalBlockSizeException | BadPaddingException | NoSuchProviderException
				| InvalidAlgorithmParameterException | UnsupportedEncodingException e) {
			e.printStackTrace();
			tip = new Tip(1, "加密失败");
		} catch (IOException e) {
			e.printStackTrace();
			tip = new Tip(1, "请求异常");
		}

		return tip;
	}

    /**
     * 跳转到后台首页
     * @return 后台首页页面
     */
    @RequestMapping(value="/index")
    public ModelAndView index(){
        return new ModelAndView("manager/index");
    }

    /**
     * 跳转到欢迎页面
     * @return 欢迎页面
     */
    @RequestMapping(value="/home")
    public ModelAndView home(String phone, String lat, String lng, Model model){
    	model.addAttribute("rescuePhone", phone);
    	model.addAttribute("lat", lat);
    	model.addAttribute("lng", lng);
        return new ModelAndView("manager/body/home");
    }

    @Resource
    private ParkDepotService parkDepotService;
    
    @Resource
    private UserService userService;

    @Resource
    private HikBillService hikBillService;

    @Resource
    private UserPlateService userPlateService;
    
    @Resource
    private PersonalMessageService personalMesssageService;

}
